#include  <math.h>
#include "..\inc\44b.h"
#include "..\inc\44blib.h"
#include "..\inc\def.h"
#include "..\inc\rtc.h"

void stopPort(void);
void ReturnPort(void);


static void __irq STAlarmInt(void);
static void __irq STEint0Int(void);

char wake_int=0;
void Test_StopMode(void)
{
    unsigned int i, j, portStatus[20];
    unsigned int *memdata,*temp;
    
    memdata = (unsigned int *)malloc(0x100000);
    temp=memdata;

    for(i=0;i<0x40000;i++)
	*(temp+i)=i;

    rLOCKTIME=0xfff;

    for(i=0;i<20;i++)
	portStatus[i]=*( (volatile U32 *)(0x1d20000+(i<<2)) );

    Uart_Printf("[STOP Mode Test]\n");
    Uart_Printf("After 5 seconds, S3C44B0X will wake up by RTC alarm interrupt.\n");
    Uart_Printf("S3C44B0X will also wake up by keyboard.\n\n");
    Uart_TxEmpty(0);	//Wait until UART0 Tx buffer empty.
    
    Rtc_Init();

    rALMYEAR=TESTYEAR2 ;
    rALMMON =TESTMONTH2;
    rALMDAY =TESTDAY2  ;
    rALMHOUR=TESTHOUR2 ;
    rALMMIN =TESTMIN2  ;
    rALMSEC =TESTSEC2+4; 
	    
    rRTCALM=0x7f;   //Start RTC alarm

    pISR_RTC=(U32)STAlarmInt;
    pISR_EINT0=(U32)STEint0Int;
    
    rINTMSK=BIT_GLOBAL;//Before entering Stop mode interrupts must be masked!!

    stopPort();

    EnterPWDN(0x1);//Entering Power down mode.

    rCLKCON=0x7ff8; //Thaw mode -> normal mode.

    rINTMSK=~(BIT_GLOBAL|BIT_RTC|BIT_EINT0);

    for(i=0;i<20;i++)// Retrun original port configurations 
        *( (volatile U32 *)(0x1d20000+(i<<2)) )=portStatus[i];

    rRTCCON = 0x01; //R/W enable to write rRTCALM
    rRTCALM = 0x0;  //Stop RTC alram
    rRTCCON = 0x0;  //R/W disable :Stop RTC

    rINTMSK =BIT_GLOBAL;//diable all interrupt.

    switch(wake_int)
    {
	case 1:
	    Uart_Printf("S3C44B0X is waked by Alarm\n");
	    break;
	case 2:
	    Uart_Printf("S3C44B0X is waked by EINT0\n");
	    break;
	default :
	    Uart_Printf("Check int!!!\n");
	    break;
    }
    
    Uart_Printf("Return to Normal Mode.\n");    

    Uart_Printf("Self-refresh data verifing...\n");
    for(i=0;i<0x40000;i++)
    {
	j=*(temp+i);
	if(j!=i)
	{
	    Uart_Printf("Memory test fail after Self-refresh\n"); 
	    break;
	}
    }
    if(j+1==i)
	Uart_Printf("Stop mode and self-refresh test O.K.\n");

    free(memdata);
    wake_int=0;

}
void __irq STEint0Int(void)
{
    rI_ISPC=BIT_EINT0;	//clear pending_bit
    wake_int=2;
}

void __irq STAlarmInt(void)
{
    rI_ISPC=BIT_RTC;   
    //rI_ISPC; //is needed only when cache=on & wrbuf=on & BSFRD=0
    wake_int=1;
}

void stopPort(void)
{
// The I/O ports have to be configured 
// properly to reduce STOP mode current.
// pullup + output=high
    rPCONA=0x3ff;    //ROM addr:16,17,18,19 SDRAM bank addr:21,22

    rPCONB=0x7ff;	    //SDRAM:SCKE,SCLK,nSCAS,nSRAS

    rPDATC=0x0;
    rPCONC=0x10000000;	//all output
    rPUPC=0xc000;

    rPDATD=0x0;
    rPCOND=0x5555;	//all output

    rPDATE=0x0;
    rPCONE=0x404;	//all output
    rPUPE=0x106;

    rPDATF=0x0;
    rPCONF=0x00;	//all output
    rPUPF=0x1e3;

    rPDATG=0x0;
    rPCONG=0x55aa;	//all output
    rPUPG=0x0;

    rSPUCR=0x0;		
    rEXTINT=0x22222222;	//falling edge

    rRTCCON=0x0;    //RTC R/W disable for power consumption
    rADCCON |=0x20; //ADC sleep mode
}

